package com.zt.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zt.entity.UserCoupons;
import com.zt.service.CouponDistributionCacheService;
import com.zt.vo.CouponDistributionStatsVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 优惠券发放缓存服务实现类
 */
@Service
@Slf4j
public class CouponDistributionCacheServiceImpl implements CouponDistributionCacheService {
    
    @Autowired
    @Qualifier("stringRedisTemplate")
    private StringRedisTemplate redisTemplate;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    // Redis键前缀 - 只保留实际使用的键
    private static final String USER_COUPONS_DETAIL_PREFIX = "coupons:";
    
    @Override
    public void cacheUserCoupon(UserCoupons userCoupon) {
        try {
            // 已禁用非coupons:键的缓存 - 只保留coupons:开头的键
            // 1. 缓存到用户优惠券集合中 - 已禁用
            // String userCouponsKey = USER_COUPONS_PREFIX + userCoupon.getUserId();
            // redisTemplate.opsForSet().add(userCouponsKey, userCoupon.getCouponId().toString());
            // redisTemplate.expire(userCouponsKey, USER_COUPONS_TTL, TimeUnit.HOURS);

            // 2. 缓存用户-优惠券检查结果 - 已禁用
            // String checkKey = USER_COUPON_CHECK_PREFIX + userCoupon.getUserId() + ":" + userCoupon.getCouponId();
            // redisTemplate.opsForValue().set(checkKey, "1", COUPON_CHECK_TTL, TimeUnit.HOURS);

            // 3. 缓存到优惠券发放记录中 - 已禁用
            // cacheDistributionRecord(userCoupon.getCouponId(), userCoupon.getUserId(), userCoupon);

            log.debug("用户优惠券缓存已禁用: userId={}, couponId={}", userCoupon.getUserId(), userCoupon.getCouponId());
            
            log.debug("缓存用户优惠券: userId={}, couponId={}", userCoupon.getUserId(), userCoupon.getCouponId());
        } catch (Exception e) {
            log.error("缓存用户优惠券失败: userId={}, couponId={}", userCoupon.getUserId(), userCoupon.getCouponId(), e);
        }
    }
    
    @Override
    public void batchCacheUserCoupons(List<UserCoupons> userCoupons) {
        if (userCoupons == null || userCoupons.isEmpty()) {
            return;
        }
        
        try {
            // 按用户分组
            Map<Integer, List<UserCoupons>> userCouponMap = new HashMap<>();
            for (UserCoupons userCoupon : userCoupons) {
                userCouponMap.computeIfAbsent(userCoupon.getUserId(), k -> new ArrayList<>()).add(userCoupon);
            }
            
            // 批量缓存 - 已禁用非coupons:键
            // for (Map.Entry<Integer, List<UserCoupons>> entry : userCouponMap.entrySet()) {
            //     Integer userId = entry.getKey();
            //     List<UserCoupons> coupons = entry.getValue();
            //
            //     String userCouponsKey = USER_COUPONS_PREFIX + userId;
            //     String[] couponIds = coupons.stream()
            //         .map(uc -> uc.getCouponId().toString())
            //         .toArray(String[]::new);
            //
            //     redisTemplate.opsForSet().add(userCouponsKey, couponIds);
            //     redisTemplate.expire(userCouponsKey, USER_COUPONS_TTL, TimeUnit.HOURS);
            //
            //     // 批量缓存检查结果
            //     for (UserCoupons userCoupon : coupons) {
            //         String checkKey = USER_COUPON_CHECK_PREFIX + userId + ":" + userCoupon.getCouponId();
            //         redisTemplate.opsForValue().set(checkKey, "1", COUPON_CHECK_TTL, TimeUnit.HOURS);
            //     }
            // }

            log.debug("批量用户优惠券缓存已禁用: {} 条记录", userCoupons.size());
            
            log.debug("批量缓存用户优惠券: 总数={}", userCoupons.size());
        } catch (Exception e) {
            log.error("批量缓存用户优惠券失败", e);
        }
    }
    
    @Override
    public Set<Integer> getUserCouponIds(Integer userId) {
        // 已禁用 user:coupons 键的使用
        log.debug("getUserCouponIds已禁用: userId={}", userId);
        return new HashSet<>();
    }
    
    @Override
    public Boolean hasUserCouponFromCache(Integer userId, Integer couponId) {
        // 已禁用 user:coupon:check 键的使用
        // 直接返回null，让调用方从数据库查询
        log.debug("hasUserCouponFromCache已禁用，userId={}, couponId={}", userId, couponId);
        return null; // 缓存未命中，强制从数据库查询
    }
    
    @Override
    public void cacheCouponDistributionStats(Integer couponId, CouponDistributionStatsVO stats) {
        // 已禁用 coupon:stats 键的使用
        log.debug("cacheCouponDistributionStats已禁用: couponId={}", couponId);
    }
    
    @Override
    public CouponDistributionStatsVO getCouponDistributionStatsFromCache(Integer couponId) {
        // 已禁用 coupon:stats 键的使用
        log.debug("getCouponDistributionStatsFromCache已禁用: couponId={}", couponId);
        return null;
    }
    
    @Override
    public void incrementCouponDistributedCount(Integer couponId, Integer count) {
        // 已禁用 coupon:distributed:count 键的使用
        log.debug("incrementCouponDistributedCount已禁用: couponId={}, count={}", couponId, count);
    }
    
    @Override
    public Integer getCouponDistributedCountFromCache(Integer couponId) {
        // 已禁用 coupon:distributed:count 键的使用
        log.debug("getCouponDistributedCountFromCache已禁用: couponId={}", couponId);
        return null; // 强制从数据库查询
    }
    
    @Override
    public void deleteUserCouponCache(Integer userId) {
        try {
            // 已禁用非coupons:键的删除
            // String userCouponsKey = USER_COUPONS_PREFIX + userId;
            // redisTemplate.delete(userCouponsKey);

            // 删除相关的检查缓存（使用模式匹配） - 已禁用
            // String checkPattern = USER_COUPON_CHECK_PREFIX + userId + ":*";
            // Set<String> keys = redisTemplate.keys(checkPattern);
            // if (keys != null && !keys.isEmpty()) {
            //     redisTemplate.delete(keys);
            // }

            log.debug("删除用户优惠券缓存已禁用: userId={}", userId);
        } catch (Exception e) {
            log.error("删除用户优惠券缓存失败: userId={}", userId, e);
        }
    }
    
    @Override
    public void deleteCouponDistributionStatsCache(Integer couponId) {
        // 已禁用相关键的删除操作
        log.debug("deleteCouponDistributionStatsCache已禁用: couponId={}", couponId);
    }
    
    @Override
    public void cacheDistributionRecord(Integer couponId, Integer userId, UserCoupons userCoupon) {
        // 已禁用 coupon:distribution:records 键的使用
        log.debug("cacheDistributionRecord已禁用: couponId={}, userId={}", couponId, userId);
    }
    
    @Override
    public List<UserCoupons> getCouponDistributionRecords(Integer couponId) {
        // 已禁用 coupon:distribution:records 键的使用
        log.debug("getCouponDistributionRecords已禁用: couponId={}", couponId);
        return new ArrayList<>();
    }

    @Override
    public void cacheUserCouponsDetail(Integer userId, List<Map<String, Object>> coupons, Integer expireDays) {
        try {
            String key = USER_COUPONS_DETAIL_PREFIX + userId;
            String value = objectMapper.writeValueAsString(coupons);
            redisTemplate.opsForValue().set(key, value, expireDays, TimeUnit.DAYS);
            log.debug("缓存用户优惠券详细信息: userId={}, count={}, expireDays={}", userId, coupons.size(), expireDays);
        } catch (Exception e) {
            log.error("缓存用户优惠券详细信息失败: userId={}", userId, e);
        }
    }

    @Override
    public List<Map<String, Object>> getUserCouponsDetail(Integer userId) {
        try {
            String key = USER_COUPONS_DETAIL_PREFIX + userId;
            String value = redisTemplate.opsForValue().get(key);
            if (value != null) {
                TypeReference<List<Map<String, Object>>> typeRef = new TypeReference<List<Map<String, Object>>>() {};
                return objectMapper.readValue(value, typeRef);
            }
        } catch (Exception e) {
            log.error("获取用户优惠券详细信息失败: userId={}", userId, e);
        }
        return new ArrayList<>();
    }

    @Override
    public void addCouponToUserDetail(Integer userId, Map<String, Object> couponDetail, Integer expireDays) {
        try {
            String key = USER_COUPONS_DETAIL_PREFIX + userId;

            // 获取现有的优惠券列表
            List<Map<String, Object>> existingCoupons = getUserCouponsDetail(userId);

            // 检查是否已存在相同ID的优惠券
            Integer couponId = (Integer) couponDetail.get("id");
            boolean exists = existingCoupons.stream()
                .anyMatch(coupon -> couponId.equals(coupon.get("id")));

            if (!exists) {
                // 添加新优惠券
                existingCoupons.add(couponDetail);

                // 重新缓存
                String value = objectMapper.writeValueAsString(existingCoupons);
                redisTemplate.opsForValue().set(key, value, expireDays, TimeUnit.DAYS);
                log.debug("添加优惠券到用户详细信息缓存: userId={}, couponId={}", userId, couponId);
            } else {
                log.debug("优惠券已存在于用户详细信息缓存中: userId={}, couponId={}", userId, couponId);
            }
        } catch (Exception e) {
            log.error("添加优惠券到用户详细信息缓存失败: userId={}", userId, e);
        }
    }
}
